<script lang="ts" setup>
  import { computed, ref, useSlots, watch } from 'vue'
  import type { MenuProps } from 'ant-design-vue'
  import { Dropdown, InputSearch, Menu, MenuDivider } from 'ant-design-vue'
  import { useDebounceFn } from '@vueuse/core'
  import { ToolbarEnum } from '../types/tree'
  import { Icon } from '/@/components/Icon'
  import { BasicTitle } from '/@/components/Basic'
  import { useI18n } from '/@/hooks/web/useI18n'
  import { createBEM } from '/@/utils/bem'

  const props = defineProps({
    helpMessage: {
      type: [String, Array] as PropType<string | string[]>,
      default: '',
    },
    title: {
      type: String,
      default: '',
    },
    toolbar: {
      type: Boolean,
      default: false,
    },
    // 是否显示toolbar的 层级关联/层级独立按钮
    showStrictlyButton: {
      type: Boolean,
      default: true,
    },
    checkable: {
      type: Boolean,
      default: false,
    },
    search: {
      type: Boolean,
      default: false,
    },
    searchText: {
      type: String,
      default: '',
    },
    checkAll: {
      type: Function,
      default: undefined,
    },
    expandAll: {
      type: Function,
      default: undefined,
    },
  } as const)

  const emit = defineEmits(['strictly-change', 'search'])

  const searchValue = ref('')

  const [bem] = createBEM('tree-header')

  const slots = useSlots()
  const { t } = useI18n()

  const getInputSearchCls = computed(() => {
    const titleExists = slots.headerTitle || props.title
    return [
      'mr-1',
      'w-full',
      {
        'ml-5': titleExists,
      },
    ]
  })

  const toolbarList = computed(() => {
    const { checkable, showStrictlyButton } = props
    const defaultToolbarList = [
      { label: t('component.tree.expandAll'), value: ToolbarEnum.EXPAND_ALL },
      {
        label: t('component.tree.unExpandAll'),
        value: ToolbarEnum.UN_EXPAND_ALL,
        divider: checkable,
      },
    ]

    const retList = [
      {
        label: t('component.tree.selectAll'),
        value: ToolbarEnum.SELECT_ALL,
      },
      {
        label: t('component.tree.unSelectAll'),
        value: ToolbarEnum.UN_SELECT_ALL,
        divider: checkable,
      },
      ...defaultToolbarList,
    ]
    if (showStrictlyButton) {
      retList.push(
        ...[
          {
            label: t('component.tree.checkStrictly'),
            value: ToolbarEnum.CHECK_STRICTLY,
          },
          {
            label: t('component.tree.checkUnStrictly'),
            value: ToolbarEnum.CHECK_UN_STRICTLY,
          },
        ],
      )
    }
    return checkable ? retList : defaultToolbarList
  })

  const handleMenuClick: MenuProps['onClick'] = ({ key }) => {
    switch (key) {
      case ToolbarEnum.SELECT_ALL:
        props.checkAll?.(true)
        break
      case ToolbarEnum.UN_SELECT_ALL:
        props.checkAll?.(false)
        break
      case ToolbarEnum.EXPAND_ALL:
        props.expandAll?.(true)
        break
      case ToolbarEnum.UN_EXPAND_ALL:
        props.expandAll?.(false)
        break
      case ToolbarEnum.CHECK_STRICTLY:
        emit('strictly-change', false)
        break
      case ToolbarEnum.CHECK_UN_STRICTLY:
        emit('strictly-change', true)
        break
    }
  }

  function emitChange(value?: string): void {
    emit('search', value)
  }

  const debounceEmitChange = useDebounceFn(emitChange, 200)

  watch(
    () => searchValue.value,
    (v) => {
      debounceEmitChange(v)
    },
  )

  watch(
    () => props.searchText,
    (v) => {
      if (v !== searchValue.value) searchValue.value = v
    },
  )
</script>

<template>
  <div :class="bem()" class="flex items-center px-2 py-1.5">
    <slot v-if="slots.headerTitle" name="headerTitle"></slot>
    <BasicTitle v-if="!slots.headerTitle && title" :help-message="helpMessage">
      {{ title }}
    </BasicTitle>
    <div
      v-if="search || toolbar"
      class="flex flex-1 cursor-pointer items-center justify-self-stretch"
    >
      <div v-if="search" :class="getInputSearchCls">
        <InputSearch
          v-model:value="searchValue"
          :placeholder="t('common.searchText')"
          allow-clear
        />
      </div>
      <Dropdown v-if="toolbar" @click.prevent>
        <Icon icon="ion:ellipsis-vertical" />
        <template #overlay>
          <Menu @click="handleMenuClick">
            <template v-for="item in toolbarList" :key="item.value">
              <Menu.Item v-bind="{ key: item.value }">
                {{ item.label }}
              </Menu.Item>
              <MenuDivider v-if="item.divider" />
            </template>
          </Menu>
        </template>
      </Dropdown>
    </div>
  </div>
</template>
